//
// Created by 王岩松 on 2020/3/24.
//

#ifndef FORMANT_FORMANT_H
#define FORMANT_FORMANT_H

//    sound A("C:\\Users\\王岩松\\Desktop\\C4_1_y.wav");
//    cerr << "sound get" << endl;
//
//    ofstream fout("C:\\Users\\王岩松\\Desktop\\C4_1_y.txt");
//
//    Formant ff = Sound_to_Formant_burg(A, 0.00625, 4, 5500, 0.05 / 2, 50);
//    double time = 0.028125;
//    while(time <= 3.971875 + 0.001) {
//        fout << fixed << setprecision(6) << time << "\t";
//        for(int i = 1; i <= 4; ++ i) {
//            fout << fixed << setprecision(3) << ff.getFormantAtX(time, i) << "\t";
//        } fout << endl;
//        time = time + 0.00625;
//    }

#include <vector>
#include <iostream>
#include <assert.h>
#include "roots.h"
#include "lpc.h"
#include "sound.h"

using namespace std;

struct Formant_frame{
    int nFormant;
    vector<double> frequnecy; // 共振峰频率
    vector<double>  bandwidth; // 带宽
};
struct Formant{
    vector<Formant_frame> frames;
    double physicalDuration;
    int nFrames;
    double dt;
    double t1;
    void Formant_create(double _physicalDuration, int _nFrames, double _dt, double _t1);
    double Sampled_indexToX(int index);
    int Sampled_xToLowIndex(double time);
    double getFormantAtX(double time, int NF, bool interpolate);
    void Free();

    template <class T>
    static void freeVector(vector<T> &A){
        vector<T>().swap(A);
    }
    template <class T>
    static void freeVV(vector<vector<T>> &A){
        for(int i = 0; i < A.size(); ++ i) {
            freeVector(A[i]);
        }
        freeVector(A);
    }
};
//void Formant::Formant_create(double _physicalDuration, int _nFrames, double _dt, double _t1);
//double Formant::Sampled_indexToX(int index);
//int Formant::Sampled_xToLowIndex(double time);

// time 时间/s NF=1/2/3... 第1/2/3...共振峰 interpolate 是否插值
//double Formant::getFormantAtX(double time, int NF, bool interpolate = true);

//void Formant::Free();

void burg(const vector<double> &samples, int p, double nyquistFrequency, double safetyMargin, int &nFormant,
                 vector<double> &formant, vector<double> &bandwidth);

void Sound_preEmphasis (sound &data, double preEmphasisFrequency);

void Formant_sort (Formant &me);

Formant Sound_to_Formant_any_inplace(sound data, double dt_in, int numberOfPoles,
        double halfdt_window, double preemphasisFrequency, double safetyMargin);

Formant Sound_to_Formant_any (sound me, double dt, int numberOfPoles, double maximumFrequency,
                                  double halfdt_window, double preemphasisFrequency, double safetyMargin);

Formant Sound_to_Formant_burg(sound me, double dt, double nFormants, double maximumFrequency, double halfdt_window, double preemphasisFrequency);

#endif //FORMANT_FORMANT_H
